(ns com.yawmark.euler.clj.e12
    (:use clojure.contrib.def
          [clojure.contrib.seq-utils :only (find-first)]
          [clojure.contrib.lazy-seqs :only (primes)]))

; (defn triangle-numbers []
;   (map first (iterate (fn [[a b]] [(+ a b) (inc b)]) [1 2])))

(defn triangle [n]
  (/ (* n (+ n 1)) 2))

(defn triangle-numbers []
  (map triangle (iterate inc 1)))

(defn prime-factors-of [num]
  "Returns a sorted list of prime factors of num, including multiplicity."
  (let [q (Math/sqrt num)
        factor? (fn [nom den] (zero? (rem nom den)))]
    (loop [n num
           d 2
           r []]
      (cond
       (> d q) (concat r [n])
       (= n d) (concat r [n])
       (factor? n d) (recur (/ n d) d (conj r d))
       :else         (recur n (inc d) r)))))

(defn count-divisors [n]
  (let [freqs (reduce #(assoc %1 %2 (inc (get %1 %2 0)))
                      {} (prime-factors-of n))]
    (reduce #(* %1 (inc %2)) 1 (vals freqs))))

; (defn euler-12 []
;   (first (drop-while #(> 500 (count-divisors %)) (triangle-numbers))))

(defn euler-12 []
  (find-first #(> (count-divisors %) 500) (triangle-numbers)))
   
